package org.tlang.type;

public class FuncType extends Type {
    private final Type returnType;
    private final Type[] parameterTypes;
    private final String name;

    public FuncType(String name, Type returnType, Type[] parameterTypes) {
        this.name = name;
        this.returnType = returnType;
        this.parameterTypes = parameterTypes;
    }

    public boolean matchParameterTypes(Type[] parameterTypes) {
        if (parameterTypes.length != this.parameterTypes.length) {
            return false;
        }

        for (int i = 0; i < parameterTypes.length; i++) {
            if (!parameterTypes[i].isTypeOf(this.parameterTypes[i])) {
                return false;
            }
        }

        return true;
    }

    @Override
    public boolean isTypeOf(Type type) {
        if (!(type instanceof FuncType)) {
            return false;
        }
        FuncType funcType = (FuncType) type;
        return matchParameterTypes(funcType.parameterTypes) && returnType.isTypeOf(funcType.returnType);
    }

    public Type returnType() {
        return returnType;
    }

    @Override
    public boolean isFuncType() {
        return true;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder(name).append("(");
        String sep = "";
        for (Type parameterType : this.parameterTypes) {
            builder.append(sep).append(parameterType);
            sep = ",";
        }
        builder.append(") -> ").append(returnType);
        return builder.toString();
    }
}
